package com.stars.controller.sys;


import com.stars.common.base.BaseCode;
import com.stars.common.base.BaseConstant;
import com.stars.common.base.ResultMsg;
import com.stars.common.jwt.JWTInfo;
import com.stars.common.jwt.JWTUtil;
import com.stars.common.valid.VerifyCodeUtils;
import com.stars.config.RsaKey;
import com.stars.controller.BaseController;
import com.stars.controller.advice.CommonExceptionHandler;
import com.stars.entity.dto.sys.SystemPermissionDTO;
import com.stars.entity.dto.sys.SystemUserAppOrgDTO;
import com.stars.services.system.AuthAccessService;
import com.stars.services.system.UserAccessService;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @author : alex
 * @version ：1.0.0
 * @Date : create by 2017/12/1 17:39
 * @description ：认证控制层
 * @note 注意事项
 */
@Slf4j
@RestController
@RequestMapping("/auth")
@Api(tags="用户认证")
public class AuthController extends BaseController {


    @Autowired
    private UserAccessService userAccessServiceImpl;
    @Autowired
    private RsaKey rsaKey;
    @Autowired
    private AuthAccessService authAccessServiceImpl;

    /**
     * 验证登录，并生成token
     *
     * @param username
     * @return password
     * @throws Exception
     */
    @PostMapping(value = "/token")
    @ApiOperation(value = "验证登录，并生成token",notes = "验证登录，并生成token")
    public ResultMsg getToken(String username, String password) throws Exception {
        /** 帐号或密码不能为空 **/
        if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
            return ResultMsg.customMsg(BaseCode.VLIDATE_PARM, "帐号或密码不能为空", null);
        }
        /** 调用验证用户 **/
        SystemUserAppOrgDTO systemUser = userAccessServiceImpl.authUser(username, password);
        if (systemUser == null) {
            return ResultMsg.customMsg(BaseCode.VLIDATE_PARM, "帐号或者密码错误", "帐号或者密码错误");
        }
        /** 加密生成token操作 **/
        //此处使用用户名，用户id,真实姓名进行加密，密码不参与密钥串加密
        JWTInfo jwtInfo =new JWTInfo(systemUser.getUserName(), systemUser.getId(), systemUser.getUserRealName());
        String token = JWTUtil.generateToken(jwtInfo, rsaKey.getExpireTime(), rsaKey.getPrikey());
        /** 登录成功，将token加入redis**/
        return authAccessServiceImpl.authLogin(systemUser.getId(),token);
    }

    @PostMapping(value = "/logout")
    @ApiOperation(value = "退出登录",notes = "退出登录")
    public ResultMsg loginOut(HttpServletRequest request) throws Exception{
        String sToken = request.getHeader(BaseConstant.ACCESS_TOKEN);
        authAccessServiceImpl.authOutLogin(sToken);
        return ResultMsg.success();
    }
    @PostMapping(value = "/isLogined")
    @ApiOperation(value = "用户是否登录",notes = "用户是否登录")
    public ResultMsg isLogined(HttpServletRequest request){
        String sToken = request.getHeader(BaseConstant.ACCESS_TOKEN);
        if (null != sToken) {
          return   ResultMsg.success(sToken);
        }
       return ResultMsg.failure("尚未登录");
    }

    /**
     * 根据token获取该用户拥有的资源
     *
     * @return
     * @throws Exception
     */
    @PostMapping(value = "/getPermission")
    @ApiOperation(value = "根据token获取该用户拥有的资源",notes = " ")
    public ResultMsg getPermission(HttpServletRequest request) throws Exception {
        String accessToken = request.getHeader(BaseConstant.ACCESS_TOKEN);
        //解密后，我们就知道是谁了。然后进行下一步操作
        Jws<Claims> claimsJws = JWTUtil.parserToken(accessToken, rsaKey.getPubkey());
        Object userId = claimsJws.getBody().get(BaseConstant.USER_ID);
        SystemPermissionDTO dto = new SystemPermissionDTO();
        dto.setUserId(userId.toString());
        List<SystemPermissionDTO> permissionList = authAccessServiceImpl.findAllTreeMenusList(dto);
        Map<String,Object> map = new HashMap<>();
        map.put(BaseConstant.PERMISSIONS,permissionList);
        return ResultMsg.success(permissionList);
    }
    /**
     * 获取全部的资源数据
     *
     * @return
     * @throws Exception
     */
    @PostMapping("/getAllMenus")
    @ApiOperation(value = "获取全部的资源数据",notes = "获取全部的资源数据")
    public ResultMsg getAllMenus(SystemPermissionDTO systemPermissionDTO,HttpServletRequest request) throws Exception {
        SystemUserAppOrgDTO userInfo = getUserInfo(request);
        systemPermissionDTO.setUserId(userInfo.getId());
        List<SystemPermissionDTO> byAll = authAccessServiceImpl.findAllMenus(systemPermissionDTO);
        return ResultMsg.success(byAll);

    }
    /**
     * 获取全部的资源数据
     *
     * @return
     * @throws Exception
     */
    @PostMapping("/getAllTreeMenusList")
    @ApiOperation(value = "获取全部的资源数据",notes = "获取全部的资源数据")
    public ResultMsg getAllTreeMenusList(SystemPermissionDTO systemPermissionDTO,HttpServletRequest request) throws Exception {
        List<SystemPermissionDTO> byAll = authAccessServiceImpl.findAllTreeMenusList(systemPermissionDTO);
        return ResultMsg.success(byAll);
    }
    /**
     * 根据角色id查询该角色锁拥有的资源
     *
     * @param dto
     * @return
     * @throws Exception
     */
    @PostMapping(value = "/getRolePermission")
    @ApiOperation(value = "根据角色id查询该角色拥有的资源",notes = "根据角色id查询该角色拥有的资源")
    public ResultMsg getRolePermission(SystemPermissionDTO dto) throws Exception {
        List<SystemPermissionDTO> byRoleId = authAccessServiceImpl.findByRoleId(dto);
        return ResultMsg.success(byRoleId);
    }
    /**
     * 根据用户id查询该用户拥有的资源
     * @param dto
     * @return
     * @throws Exception
     */
    @PostMapping(value = "/getUserPermission")
    @ApiOperation(value = "根据用户id查询该用户拥有的资源",notes = "根据用户id查询该用户拥有的资源")
    public ResultMsg getUserPermission(SystemPermissionDTO dto) throws Exception {
        List<SystemPermissionDTO> byRoleId = authAccessServiceImpl.findUserMenusTreeList(dto);
        return ResultMsg.success(byRoleId);
    }
    /**
     * 根据组织id查询该组织拥有的资源
     * @param dto
     * @return
     * @throws Exception
     */
    @PostMapping(value = "/getOrgPermission")
    @ApiOperation(value = "根据组织id查询该组织拥有的资源",notes = "根据组织id查询该组织拥有的资源")
    public ResultMsg getOrgPermission(SystemPermissionDTO dto) throws Exception {
        List<SystemPermissionDTO> byRoleId = authAccessServiceImpl.findOrgMenusTreeList(dto);
        return ResultMsg.success(byRoleId);
    }
    @GetMapping(value = "/getCode")
    @ApiOperation(value = "验证码",notes = "验证码")
    public void getYzm(HttpServletResponse response, HttpServletRequest request) {
        try {
            response.setHeader("Pragma", "No-cache");
            response.setHeader("Cache-Control", "no-cache");
            response.setDateHeader("Expires", 0);
            response.setContentType("image/jpg");

            //生成随机字串
            String verifyCode = VerifyCodeUtils.generateVerifyCode(4);
            log.info("verifyCode:{}", verifyCode);
            //存入会话session
            HttpSession session = request.getSession(true);
            session.setAttribute("_code", verifyCode.toLowerCase());
            //生成图片
            int w = 146, h = 33;
            VerifyCodeUtils.outputImage(w, h, response.getOutputStream(), verifyCode);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}
